<template>
  <div class="cm-editor">
    <div id="editor-header">
      <div>
        <i class="iconfont"
           @click="getResult()">&#xe77c;</i>
        <i class="iconfont"
           @click="undo()">&#xe774;</i>
        <i class="iconfont"
           @click="redo()">&#xe77d;</i>
      </div>
      <div>
        <i class="iconfont"
           @click="open()">&#xe77f;</i>
        <i class="iconfont"
           @click="clear()">&#xe777;</i>
        <i class="iconfont"
           @click="refresh()">&#xe772;</i>
        <i class="iconfont"
           v-if="!this.options.fullScreen"
           @click="fullScreen()">&#xe76f;</i>
        <i class="iconfont"
           v-else
           @click="fullScreen()">&#xe771;</i>
      </div>
    </div>
    <textarea id="coder"
              v-model="code" />
  </div>
</template>

<script>
import './init'
import { options } from './options'
import { _debounce } from '@/utils/debounce'
import { interpret } from '@/api/code'
import { mapGetters } from 'vuex'
// 引入全局实例
import _CodeMirror from 'codemirror'
// 获取全局实例
const CodeMirror = window.CodeMirror || _CodeMirror

export default {
  name: 'Editor',
  mixins: [options],
  data () {
    return {
      code: '',
      mode: 'x-python',
      editor: null
    }
  },
  computed: {
    ...mapGetters(['userid'])
  },
  mounted () {
    this.initEditor()
  },
  methods: {
    initEditor () {
      // 初始化编辑器实例，传入需要被实例化的文本域对象和默认配置
      this.editor = CodeMirror.fromTextArea(
        document.getElementById('coder'),
        this.options
      )
      this.editor.setValue(this.code)
      this.editor.on('change', editor => {
        // 双向绑定code
        this.code = editor.getValue()
      })
      this.editor.on('keypress', () => {
        // 自动提示
        this.editor.showHint()
      })
    },
    undo () {
      this.editor.undo()
    },
    redo () {
      this.editor.redo()
    },
    refresh () {
      this.editor.refresh()
      document.getElementById('output').innerText = ''
    },
    fullScreen () {
      var nav = document.getElementById('editor-header')
      if (!this.editor.options.fullScreen) {
        this.options.fullScreen = true
        this.editor.setOption('fullScreen', true)
        nav.style.setProperty('position', 'fixed')
        nav.style.setProperty('top', '0')
        nav.style.setProperty('left', '0')
        nav.style.setProperty('right', '0')
        nav.style.setProperty('border-radius', '0')
        nav.style.setProperty('z-index', '10')
      } else {
        this.options.fullScreen = false
        this.editor.setOption('fullScreen', false)
        nav.style.setProperty('position', 'static')
        nav.style.setProperty('border-radius', '6px 6px 0 0')
        nav.style.setProperty('z-index', '0')
      }
    },
    getResult: _debounce(function () {
      const userid = this.userid || ''
      interpret(this.code, userid)
        .then(res => {
          this.$emit('result', res.data)
        })
        .catch(error => {
          console.log(error)
        })
    }, 300),
    clear () {
      this.editor.setValue('')
      document.querySelector('#output').innerText = ''
    },
    open () {
      this.$emit('show', true)
    }
  }
}
</script>

<style lang="stylus">
@import '~styles/varibles.styl'

.cm-editor
  display flex
  flex-direction column
  width 48%
  box-shadow 3px 3px 5px 1px shadow-color
  #editor-header
    display flex
    justify-content space-between
    height 35px
    padding 0 14px
    background-color cm-wrapper
    border-radius 6px 6px 0 0
    .iconfont
      line-height 35px
      margin 0 5px
      color cm-icon-color
      cursor pointer
      transition color 0.15s linear
      &:hover
        color cm-icon-hover
  .CodeMirror
    min-height 70vh
    border-radius 0 0 6px 6px
    .CodeMirror-code
      line-height 19px
    .CodeMirror-linenumber
      color #C1C1C1
    .CodeMirror-scrollbar-filler
      background-color cm-bg-color
  .CodeMirror-fullscreen
    top 35px
</style>
